package com.wg.springboot.jdk.atomic;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Description:
 * @Author WuGang
 * @Date 2021/10/25 11:20
 * @Version 1.0
 */
public class Counter {

    public static AtomicInteger count = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        System.out.println(count.getAndIncrement()); //0
        System.out.println(count); //1

        final CountDownLatch latch = new CountDownLatch(100);

        for(int i=0;i<100;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Counter.inc();
                    latch.countDown();
                }
            }).start();
        }
        latch.await();

        //101 的意思是main线程里面count为1  run里面执行一百次如果不共享就是100  结果是101说明共享run里面能读取到count
        System.out.println("运行结果："+Counter.count);
        System.out.println(latch);


    }

    public static void inc(){
        try{
            Thread.sleep(1); //延迟1毫秒

        }catch (InterruptedException e){ //catch住中断异常，防止程序中断
            e.printStackTrace();

        }
        count.getAndIncrement();//count值自加1
    }

}
//如果在inc方法前面加个synchronized也能是线程安全的；
//它用来修饰一个方法或者一个代码块的时候，能够保证在同一时刻最多只有一个线程执行该段代码。
class Counter2 {
//1.volatile关键字的两层语义
//　　一旦一个共享变量（类的成员变量、类的静态成员变量）被volatile修饰之后，那么就具备了两层语义：
//            　　1）保证了不同线程对这个变量进行操作时的可见性，即一个线程修改了某个变量的值，这新值对其他线程来说是立即可见的。
//            　　2）禁止进行指令重排序。
    public volatile static  Integer count = 0;

    public synchronized static void inc(){
        try{
            Thread.sleep(1); //延迟1毫秒

        }catch (InterruptedException e){ //catch住中断异常，防止程序中断
            e.printStackTrace();

        }
        count++;//count值自加1
    }


    public static void main(String[] args) throws InterruptedException {

//不加这个玩意还不行  让main线程等待我这里循环完  不等待的话run执行完就被输出了
        final CountDownLatch latch = new CountDownLatch(100);

        for(int i=0;i<100;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Counter2.inc();
                    latch.countDown();
                }
            }).start();
        }
        latch.await();

        System.out.println("运行结果Counter2："+Counter2.count);
    }
}
